package com.atguigu.gmall.search.listener;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.search.feign.GmallPmsClient;
import com.atguigu.gmall.search.feign.GmallWmsClient;
import com.atguigu.gmall.search.pojo.Goods;
import com.atguigu.gmall.search.pojo.SearchAttrValueVo;
import com.atguigu.gmall.search.repository.GoodsRepository;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class GoodsListener {

    @Autowired
    private GmallPmsClient gmallPmsClient;

    @Autowired
    private GmallWmsClient gmallWmsClient;

    @Autowired
    private GoodsRepository goodsRepository;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("SEARCH_ITEM_QUEUE"),
            exchange = @Exchange(value = "PMS_SPU_EXCHANGE",ignoreDeclarationExceptions = "true",type = ExchangeTypes.TOPIC),
            key = {"item.insert"}
    ))
    public void listen(Long spuId, Channel channel, Message message) throws IOException {
        if (spuId == null) {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            return;
        }

        // 查询spu下的sku集合
        ResponseVo<List<SkuEntity>> skusResponseVo = gmallPmsClient.querySkusBySpuId(spuId);
        List<SkuEntity> skuEntities = skusResponseVo.getData();

        try {
            // 判断当前spu下的sku是否为空
            if (!CollectionUtils.isEmpty(skuEntities)) {

                // 查询spuEntity
                ResponseVo<SpuEntity> spuEntityResponseVo = gmallPmsClient.querySpuById(spuId);
                SpuEntity spuEntity = spuEntityResponseVo.getData();

                // 查询品牌
                ResponseVo<BrandEntity> brandsResponseVo = gmallPmsClient.queryBrandById(spuEntity.getBrandId());
                BrandEntity brandEntity = brandsResponseVo.getData();

                // 查询分类
                ResponseVo<CategoryEntity> categoriesResponseVo = gmallPmsClient.queryCategoryById(spuEntity.getCategoryId());
                CategoryEntity categoryEntity = categoriesResponseVo.getData();

                // 把sku集合转化为goods集合
                List<Goods> goodsList = skuEntities.stream().map(skuEntity -> {
                    Goods goods = new Goods();

                    // sku相关信息
                    goods.setSkuId(skuEntity.getId());
                    goods.setDefaultImage(skuEntity.getDefaultImage());
                    goods.setTitle(skuEntity.getTitle());
                    goods.setSubTitle(skuEntity.getSubtitle());
                    goods.setPrice(skuEntity.getPrice().doubleValue());

                    // 新品的spu的创建时间
                    goods.setCreateTime(spuEntity.getCreateTime());

                    // 库存相关
                    ResponseVo<List<WareSkuEntity>> wareSkusResponseVo = gmallWmsClient.queryWareSkusBySkuId(skuEntity.getId());
                    List<WareSkuEntity> wareSkuEntities = wareSkusResponseVo.getData();
                    if (!CollectionUtils.isEmpty(wareSkuEntities)) {
                        goods.setStore(wareSkuEntities.stream().anyMatch(wareSkuEntity -> wareSkuEntity.getStock() > wareSkuEntity.getStockLocked()));
                        goods.setSales(wareSkuEntities.stream().map(WareSkuEntity::getSales).reduce((a, b) -> a + b).get());
                    }

                    // 品牌相关
                    if (brandEntity != null) {
                        goods.setBrandId(brandEntity.getId());
                        goods.setBrandName(brandEntity.getName());
                        goods.setLogo(brandEntity.getLogo());
                    }

                    // 分类相关
                    if (categoryEntity != null) {
                        goods.setCategoryId(categoryEntity.getId());
                        goods.setCategoryName(categoryEntity.getName());
                    }

                    /// 检索类型的规格参数及值
                    ArrayList<SearchAttrValueVo> searchAttrs = new ArrayList<>();

                    // 销售类型的检索类型的规格参数及值
                    ResponseVo<List<SkuAttrValueEntity>> skuAttrValuesResponseVo = gmallPmsClient.querySearchAttrValueBySkuIdAndCid(skuEntity.getId(), categoryEntity.getId());
                    List<SkuAttrValueEntity> skuAttrValueEntities = skuAttrValuesResponseVo.getData();
                    if (!CollectionUtils.isEmpty(skuAttrValueEntities)) {
                        searchAttrs.addAll(skuAttrValueEntities.stream().map(skuAttrValueEntity -> {
                            SearchAttrValueVo searchAttrValueVo = new SearchAttrValueVo();
                            BeanUtils.copyProperties(skuAttrValueEntity, searchAttrValueVo);
                            return searchAttrValueVo;
                        }).collect(Collectors.toList()));
                    }

                    // 基本类型的检索类型的规格参数及值
                    ResponseVo<List<SpuAttrValueEntity>> spuAttrValuesResponseVo = gmallPmsClient.querySearchAttrValueBySpuIdAndCid(spuEntity.getId(), categoryEntity.getId());
                    List<SpuAttrValueEntity> spuAttrValueEntities = spuAttrValuesResponseVo.getData();
                    if (!CollectionUtils.isEmpty(spuAttrValueEntities)) {
                        searchAttrs.addAll(spuAttrValueEntities.stream().map(spuAttrValueEntity -> {
                            SearchAttrValueVo searchAttrValueVo = new SearchAttrValueVo();
                            BeanUtils.copyProperties(spuAttrValueEntity,searchAttrValueVo);
                            return searchAttrValueVo;
                        }).collect(Collectors.toList()));
                    }

                    goods.setSearchAttrs(searchAttrs);

                    return goods;
                }).collect(Collectors.toList());

                goodsRepository.saveAll(goodsList);

                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            }
        } catch (IOException e) {
            e.printStackTrace();
            if (message.getMessageProperties().getRedelivered()){
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            } else {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
        }
    }
}
